/*
   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#ifndef __BLE_MESH_H__
#define __BLE_MESH_H__

#include "esp_ble_mesh_defs.h"
#include "esp_ble_mesh_common_api.h"

#include "sdkconfig.h"

#ifdef CONFIG_BLE_MESH_NODE

#define CID_COMPANY                    0x02E5  // 0x01A8  /**< Alibaba Incorporated */          
#define MESH_VENDOR_MODEL_ID_SERVER    0x0000  /**< Genie Vendor Model Server ID */
#define MESH_VENDOR_MODEL_ID_CLIENT    0x0001  /**< Genie Vendor Model Client ID */

/* Note: Group Address [0xC000 ~ 0XFEEE] */
#define MESH_VND_GROUP_ADDR            0xF000  /**< Genie Vendor Receive Address */
#define MESH_OTA_GROUP_ADDR            0xF100  /**< Genie OTA Group Address */
#define MESH_ALL_GROUP_ADDR            0xCFFF  /**< Genie All Product Group Address */

#define MESH_LIGHT_GROUP_ADDR          0xC001  /**< Genie Light Product Group Address */
#define MESH_SWITCH_GROUP_ADDR         0xC002  /**< Genie Switch Product Group Address */
 
#define MESH_MODEL_OP_ATTR_GET         ESP_BLE_MESH_MODEL_OP_3(0xD1,   CID_COMPANY)
#define MESH_MODEL_OP_ATTR_SET         ESP_BLE_MESH_MODEL_OP_3(0xD2,   CID_COMPANY)
#define MESH_MODEL_OP_ATTR_SET_UNACK   ESP_BLE_MESH_MODEL_OP_3(0xD3,   CID_COMPANY)
#define MESH_MODEL_OP_ATTR_STATUS      ESP_BLE_MESH_MODEL_OP_3(0xD4,   CID_COMPANY)

/* Following 4 values are as per Mesh Model specification */
#define BLE_MESH_LIGHTNESS_MIN                  0x0001
#define BLE_MESH_LIGHTNESS_MAX                  0xFFFF
#define BLE_MESH_TEMPERATURE_MIN                0x0320      // 800
#define BLE_MESH_TEMPERATURE_MAX                0x4E20      // 20000
#define BLE_MESH_TEMPERATURE_UNKNOWN            0xFFFF

#ifndef ADDRSTR
#define ADDRSTR      "%02x%02x%02x%02x%02x%02x"
#define ADDR2STR(a)  (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#endif

/* 大端数据拼接 */
#define BIG_DATA_2_OCTET(data, offset)      (data[offset] << 8 | data[offset + 1])
#define BIG_DATA_4_OCTET(data, offset)      (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3])

/*
 * function declaration
 ****************************************************************************************
 */

typedef struct {
    esp_ble_mesh_msg_ctx_t ctx;    /*!< Pointer to the context of the received message */
    uint8_t  data[16];      /*!< Rx data */
    uint8_t  len;           /*!< Rx data len */
    bool     ack;           /*!< Rx ack */
} mesh_transfer_t;
 
typedef void (*ble_mesh_recv_callback_t)(mesh_transfer_t msg);
void ble_mesh_register_callback(ble_mesh_recv_callback_t cb);

bool ble_mesh_node_is_provisioned(void);

void ble_mesh_node_delete_reset(bool prov_enable);

void ble_mesh_update_onoff_state(bool onoff);

void ble_mesh_send_onoff_status(esp_ble_mesh_msg_ctx_t ctx, uint8_t onoff);
bool ble_mesh_send_onoff_message(bool onoff);

void ble_mesh_send_vendor_status(esp_ble_mesh_msg_ctx_t ctx, uint8_t *data, uint8_t len);
bool ble_mesh_send_vendor_message(uint8_t *data, uint8_t len);

void ble_mesh_send_hsl_status(esp_ble_mesh_msg_ctx_t ctx, uint16_t hue, uint16_t saturation, uint16_t lightness);
bool ble_mesh_send_ctl_message(uint16_t lightness, uint16_t temperature);

void ble_mesh_send_ctl_status(esp_ble_mesh_msg_ctx_t ctx, uint16_t lightness, uint16_t temperature);
bool ble_mesh_send_hsl_message(uint16_t hue, uint16_t saturation, uint16_t lightness);

void ble_mesh_init(void); 

#endif /* CONFIG_BLE_MESH_NODE */

#endif /* __BLE_MESH_H__ */
